//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension ElasticLoadBalancing {
    // MARK: Enums

    // MARK: Shapes

    public struct AccessLog: AWSEncodableShape & AWSDecodableShape {
        /// The interval for publishing the access logs. You can specify an interval of either 5 minutes or 60 minutes. Default: 60 minutes
        public let emitInterval: Int?
        /// Specifies whether access logs are enabled for the load balancer.
        public let enabled: Bool
        /// The name of the Amazon S3 bucket where the access logs are stored.
        public let s3BucketName: String?
        /// The logical hierarchy you created for your Amazon S3 bucket, for example my-bucket-prefix/prod.   If the prefix is not provided, the log is placed at the root level of the bucket.
        public let s3BucketPrefix: String?

        public init(emitInterval: Int? = nil, enabled: Bool, s3BucketName: String? = nil, s3BucketPrefix: String? = nil) {
            self.emitInterval = emitInterval
            self.enabled = enabled
            self.s3BucketName = s3BucketName
            self.s3BucketPrefix = s3BucketPrefix
        }

        private enum CodingKeys: String, CodingKey {
            case emitInterval = "EmitInterval"
            case enabled = "Enabled"
            case s3BucketName = "S3BucketName"
            case s3BucketPrefix = "S3BucketPrefix"
        }
    }

    public struct AddAvailabilityZonesInput: AWSEncodableShape {
        /// The Availability Zones. These must be in the same region as the load balancer.
        @CustomCoding<StandardArrayCoder>
        public var availabilityZones: [String]
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(availabilityZones: [String], loadBalancerName: String) {
            self.availabilityZones = availabilityZones
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct AddAvailabilityZonesOutput: AWSDecodableShape {
        /// The updated list of Availability Zones for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var availabilityZones: [String]?

        public init(availabilityZones: [String]? = nil) {
            self.availabilityZones = availabilityZones
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
        }
    }

    public struct AddTagsInput: AWSEncodableShape {
        /// The name of the load balancer. You can specify one load balancer only.
        @CustomCoding<StandardArrayCoder>
        public var loadBalancerNames: [String]
        /// The tags.
        @CustomCoding<StandardArrayCoder>
        public var tags: [Tag]

        public init(loadBalancerNames: [String], tags: [Tag]) {
            self.loadBalancerNames = loadBalancerNames
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerNames = "LoadBalancerNames"
            case tags = "Tags"
        }
    }

    public struct AddTagsOutput: AWSDecodableShape {
        public init() {}
    }

    public struct AdditionalAttribute: AWSEncodableShape & AWSDecodableShape {
        /// The name of the attribute. The following attribute is supported.    elb.http.desyncmitigationmode - Determines how the load balancer handles requests that   might pose a security risk to your application. The possible values are monitor,  defensive, and strictest. The default is defensive.
        public let key: String?
        /// This value of the attribute.
        public let value: String?

        public init(key: String? = nil, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 256)
            try self.validate(self.key, name: "key", parent: name, pattern: "^[a-zA-Z0-9.]+$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^[a-zA-Z0-9.]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct AppCookieStickinessPolicy: AWSDecodableShape {
        /// The name of the application cookie used for stickiness.
        public let cookieName: String?
        /// The mnemonic name for the policy being created. The name must be unique within a set of policies for this load balancer.
        public let policyName: String?

        public init(cookieName: String? = nil, policyName: String? = nil) {
            self.cookieName = cookieName
            self.policyName = policyName
        }

        private enum CodingKeys: String, CodingKey {
            case cookieName = "CookieName"
            case policyName = "PolicyName"
        }
    }

    public struct ApplySecurityGroupsToLoadBalancerInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The IDs of the security groups to associate with the load balancer. Note that you cannot specify the name of the security group.
        @CustomCoding<StandardArrayCoder>
        public var securityGroups: [String]

        public init(loadBalancerName: String, securityGroups: [String]) {
            self.loadBalancerName = loadBalancerName
            self.securityGroups = securityGroups
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case securityGroups = "SecurityGroups"
        }
    }

    public struct ApplySecurityGroupsToLoadBalancerOutput: AWSDecodableShape {
        /// The IDs of the security groups associated with the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var securityGroups: [String]?

        public init(securityGroups: [String]? = nil) {
            self.securityGroups = securityGroups
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroups = "SecurityGroups"
        }
    }

    public struct AttachLoadBalancerToSubnetsInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The IDs of the subnets to add. You can add only one subnet per Availability Zone.
        @CustomCoding<StandardArrayCoder>
        public var subnets: [String]

        public init(loadBalancerName: String, subnets: [String]) {
            self.loadBalancerName = loadBalancerName
            self.subnets = subnets
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case subnets = "Subnets"
        }
    }

    public struct AttachLoadBalancerToSubnetsOutput: AWSDecodableShape {
        /// The IDs of the subnets attached to the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var subnets: [String]?

        public init(subnets: [String]? = nil) {
            self.subnets = subnets
        }

        private enum CodingKeys: String, CodingKey {
            case subnets = "Subnets"
        }
    }

    public struct BackendServerDescription: AWSDecodableShape {
        /// The port on which the EC2 instance is listening.
        public let instancePort: Int?
        /// The names of the policies enabled for the EC2 instance.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyNames: [String]?

        public init(instancePort: Int? = nil, policyNames: [String]? = nil) {
            self.instancePort = instancePort
            self.policyNames = policyNames
        }

        private enum CodingKeys: String, CodingKey {
            case instancePort = "InstancePort"
            case policyNames = "PolicyNames"
        }
    }

    public struct ConfigureHealthCheckInput: AWSEncodableShape {
        /// The configuration information.
        public let healthCheck: HealthCheck
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(healthCheck: HealthCheck, loadBalancerName: String) {
            self.healthCheck = healthCheck
            self.loadBalancerName = loadBalancerName
        }

        public func validate(name: String) throws {
            try self.healthCheck.validate(name: "\(name).healthCheck")
        }

        private enum CodingKeys: String, CodingKey {
            case healthCheck = "HealthCheck"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct ConfigureHealthCheckOutput: AWSDecodableShape {
        /// The updated health check.
        public let healthCheck: HealthCheck?

        public init(healthCheck: HealthCheck? = nil) {
            self.healthCheck = healthCheck
        }

        private enum CodingKeys: String, CodingKey {
            case healthCheck = "HealthCheck"
        }
    }

    public struct ConnectionDraining: AWSEncodableShape & AWSDecodableShape {
        /// Specifies whether connection draining is enabled for the load balancer.
        public let enabled: Bool
        /// The maximum time, in seconds, to keep the existing connections open before deregistering the instances.
        public let timeout: Int?

        public init(enabled: Bool, timeout: Int? = nil) {
            self.enabled = enabled
            self.timeout = timeout
        }

        private enum CodingKeys: String, CodingKey {
            case enabled = "Enabled"
            case timeout = "Timeout"
        }
    }

    public struct ConnectionSettings: AWSEncodableShape & AWSDecodableShape {
        /// The time, in seconds, that the connection is allowed to be idle (no data has been sent over the connection) before it is closed by the load balancer.
        public let idleTimeout: Int

        public init(idleTimeout: Int) {
            self.idleTimeout = idleTimeout
        }

        public func validate(name: String) throws {
            try self.validate(self.idleTimeout, name: "idleTimeout", parent: name, max: 3600)
            try self.validate(self.idleTimeout, name: "idleTimeout", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case idleTimeout = "IdleTimeout"
        }
    }

    public struct CreateAccessPointInput: AWSEncodableShape {
        /// One or more Availability Zones from the same region as the load balancer. You must specify at least one Availability Zone. You can add more Availability Zones after you create the load balancer using  EnableAvailabilityZonesForLoadBalancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var availabilityZones: [String]?
        /// The listeners. For more information, see Listeners for Your Classic Load Balancer in the Classic Load Balancers Guide.
        @CustomCoding<StandardArrayCoder>
        public var listeners: [Listener]
        /// The name of the load balancer. This name must be unique within your set of load balancers for the region, must have a maximum of 32 characters, must contain only alphanumeric characters or hyphens, and cannot begin or end with a hyphen.
        public let loadBalancerName: String
        /// The type of a load balancer. Valid only for load balancers in a VPC.           By default, Elastic Load Balancing creates an Internet-facing load balancer with a DNS name that resolves to public IP addresses. For more information about Internet-facing and Internal load balancers, see Load Balancer Scheme in the Elastic Load Balancing User Guide. Specify internal to create a load balancer with a DNS name that resolves to private IP addresses.
        public let scheme: String?
        /// The IDs of the security groups to assign to the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var securityGroups: [String]?
        /// The IDs of the subnets in your VPC to attach to the load balancer. Specify one subnet per Availability Zone specified in AvailabilityZones.
        @OptionalCustomCoding<StandardArrayCoder>
        public var subnets: [String]?
        /// A list of tags to assign to the load balancer. For more information about tagging your load balancer, see Tag Your Classic Load Balancer in the Classic Load Balancers Guide.
        @OptionalCustomCoding<StandardArrayCoder>
        public var tags: [Tag]?

        public init(availabilityZones: [String]? = nil, listeners: [Listener], loadBalancerName: String, scheme: String? = nil, securityGroups: [String]? = nil, subnets: [String]? = nil, tags: [Tag]? = nil) {
            self.availabilityZones = availabilityZones
            self.listeners = listeners
            self.loadBalancerName = loadBalancerName
            self.scheme = scheme
            self.securityGroups = securityGroups
            self.subnets = subnets
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.listeners.forEach {
                try $0.validate(name: "\(name).listeners[]")
            }
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case listeners = "Listeners"
            case loadBalancerName = "LoadBalancerName"
            case scheme = "Scheme"
            case securityGroups = "SecurityGroups"
            case subnets = "Subnets"
            case tags = "Tags"
        }
    }

    public struct CreateAccessPointOutput: AWSDecodableShape {
        /// The DNS name of the load balancer.
        public let dnsName: String?

        public init(dnsName: String? = nil) {
            self.dnsName = dnsName
        }

        private enum CodingKeys: String, CodingKey {
            case dnsName = "DNSName"
        }
    }

    public struct CreateAppCookieStickinessPolicyInput: AWSEncodableShape {
        /// The name of the application cookie used for stickiness.
        public let cookieName: String
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The name of the policy being created. Policy names must consist of alphanumeric characters and dashes (-). This name must be unique within the set of policies for this load balancer.
        public let policyName: String

        public init(cookieName: String, loadBalancerName: String, policyName: String) {
            self.cookieName = cookieName
            self.loadBalancerName = loadBalancerName
            self.policyName = policyName
        }

        private enum CodingKeys: String, CodingKey {
            case cookieName = "CookieName"
            case loadBalancerName = "LoadBalancerName"
            case policyName = "PolicyName"
        }
    }

    public struct CreateAppCookieStickinessPolicyOutput: AWSDecodableShape {
        public init() {}
    }

    public struct CreateLBCookieStickinessPolicyInput: AWSEncodableShape {
        /// The time period, in seconds, after which the cookie should be considered stale. If you do not specify this parameter, the default value is 0, which indicates that the sticky session should last for the duration of the browser session.
        public let cookieExpirationPeriod: Int64?
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The name of the policy being created. Policy names must consist of alphanumeric characters and dashes (-). This name must be unique within the set of policies for this load balancer.
        public let policyName: String

        public init(cookieExpirationPeriod: Int64? = nil, loadBalancerName: String, policyName: String) {
            self.cookieExpirationPeriod = cookieExpirationPeriod
            self.loadBalancerName = loadBalancerName
            self.policyName = policyName
        }

        private enum CodingKeys: String, CodingKey {
            case cookieExpirationPeriod = "CookieExpirationPeriod"
            case loadBalancerName = "LoadBalancerName"
            case policyName = "PolicyName"
        }
    }

    public struct CreateLBCookieStickinessPolicyOutput: AWSDecodableShape {
        public init() {}
    }

    public struct CreateLoadBalancerListenerInput: AWSEncodableShape {
        /// The listeners.
        @CustomCoding<StandardArrayCoder>
        public var listeners: [Listener]
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(listeners: [Listener], loadBalancerName: String) {
            self.listeners = listeners
            self.loadBalancerName = loadBalancerName
        }

        public func validate(name: String) throws {
            try self.listeners.forEach {
                try $0.validate(name: "\(name).listeners[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case listeners = "Listeners"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct CreateLoadBalancerListenerOutput: AWSDecodableShape {
        public init() {}
    }

    public struct CreateLoadBalancerPolicyInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The policy attributes.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyAttributes: [PolicyAttribute]?
        /// The name of the load balancer policy to be created. This name must be unique within the set of policies for this load balancer.
        public let policyName: String
        /// The name of the base policy type. 	   To get the list of policy types, use DescribeLoadBalancerPolicyTypes.
        public let policyTypeName: String

        public init(loadBalancerName: String, policyAttributes: [PolicyAttribute]? = nil, policyName: String, policyTypeName: String) {
            self.loadBalancerName = loadBalancerName
            self.policyAttributes = policyAttributes
            self.policyName = policyName
            self.policyTypeName = policyTypeName
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case policyAttributes = "PolicyAttributes"
            case policyName = "PolicyName"
            case policyTypeName = "PolicyTypeName"
        }
    }

    public struct CreateLoadBalancerPolicyOutput: AWSDecodableShape {
        public init() {}
    }

    public struct CrossZoneLoadBalancing: AWSEncodableShape & AWSDecodableShape {
        /// Specifies whether cross-zone load balancing is enabled for the load balancer.
        public let enabled: Bool

        public init(enabled: Bool) {
            self.enabled = enabled
        }

        private enum CodingKeys: String, CodingKey {
            case enabled = "Enabled"
        }
    }

    public struct DeleteAccessPointInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(loadBalancerName: String) {
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct DeleteAccessPointOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteLoadBalancerListenerInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The client port numbers of the listeners.
        @CustomCoding<StandardArrayCoder>
        public var loadBalancerPorts: [Int]

        public init(loadBalancerName: String, loadBalancerPorts: [Int]) {
            self.loadBalancerName = loadBalancerName
            self.loadBalancerPorts = loadBalancerPorts
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case loadBalancerPorts = "LoadBalancerPorts"
        }
    }

    public struct DeleteLoadBalancerListenerOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteLoadBalancerPolicyInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The name of the policy.
        public let policyName: String

        public init(loadBalancerName: String, policyName: String) {
            self.loadBalancerName = loadBalancerName
            self.policyName = policyName
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case policyName = "PolicyName"
        }
    }

    public struct DeleteLoadBalancerPolicyOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeregisterEndPointsInput: AWSEncodableShape {
        /// The IDs of the instances.
        @CustomCoding<StandardArrayCoder>
        public var instances: [Instance]
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(instances: [Instance], loadBalancerName: String) {
            self.instances = instances
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case instances = "Instances"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct DeregisterEndPointsOutput: AWSDecodableShape {
        /// The remaining instances registered with the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var instances: [Instance]?

        public init(instances: [Instance]? = nil) {
            self.instances = instances
        }

        private enum CodingKeys: String, CodingKey {
            case instances = "Instances"
        }
    }

    public struct DescribeAccessPointsInput: AWSEncodableShape {
        /// The names of the load balancers.
        @OptionalCustomCoding<StandardArrayCoder>
        public var loadBalancerNames: [String]?
        /// The marker for the next set of results. (You received this marker from a previous call.)
        public let marker: String?
        /// The maximum number of results to return with this call (a number from 1 to 400). The default is 400.
        public let pageSize: Int?

        public init(loadBalancerNames: [String]? = nil, marker: String? = nil, pageSize: Int? = nil) {
            self.loadBalancerNames = loadBalancerNames
            self.marker = marker
            self.pageSize = pageSize
        }

        public func validate(name: String) throws {
            try self.validate(self.pageSize, name: "pageSize", parent: name, max: 400)
            try self.validate(self.pageSize, name: "pageSize", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerNames = "LoadBalancerNames"
            case marker = "Marker"
            case pageSize = "PageSize"
        }
    }

    public struct DescribeAccessPointsOutput: AWSDecodableShape {
        /// Information about the load balancers.
        @OptionalCustomCoding<StandardArrayCoder>
        public var loadBalancerDescriptions: [LoadBalancerDescription]?
        /// The marker to use when requesting the next set of results. If there are no additional results, the string is empty.
        public let nextMarker: String?

        public init(loadBalancerDescriptions: [LoadBalancerDescription]? = nil, nextMarker: String? = nil) {
            self.loadBalancerDescriptions = loadBalancerDescriptions
            self.nextMarker = nextMarker
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerDescriptions = "LoadBalancerDescriptions"
            case nextMarker = "NextMarker"
        }
    }

    public struct DescribeAccountLimitsInput: AWSEncodableShape {
        /// The marker for the next set of results. (You received this marker from a previous call.)
        public let marker: String?
        /// The maximum number of results to return with this call.
        public let pageSize: Int?

        public init(marker: String? = nil, pageSize: Int? = nil) {
            self.marker = marker
            self.pageSize = pageSize
        }

        public func validate(name: String) throws {
            try self.validate(self.pageSize, name: "pageSize", parent: name, max: 400)
            try self.validate(self.pageSize, name: "pageSize", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case marker = "Marker"
            case pageSize = "PageSize"
        }
    }

    public struct DescribeAccountLimitsOutput: AWSDecodableShape {
        /// Information about the limits.
        @OptionalCustomCoding<StandardArrayCoder>
        public var limits: [Limit]?
        /// The marker to use when requesting the next set of results. If there are no additional results, the string is empty.
        public let nextMarker: String?

        public init(limits: [Limit]? = nil, nextMarker: String? = nil) {
            self.limits = limits
            self.nextMarker = nextMarker
        }

        private enum CodingKeys: String, CodingKey {
            case limits = "Limits"
            case nextMarker = "NextMarker"
        }
    }

    public struct DescribeEndPointStateInput: AWSEncodableShape {
        /// The IDs of the instances.
        @OptionalCustomCoding<StandardArrayCoder>
        public var instances: [Instance]?
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(instances: [Instance]? = nil, loadBalancerName: String) {
            self.instances = instances
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case instances = "Instances"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct DescribeEndPointStateOutput: AWSDecodableShape {
        /// Information about the health of the instances.
        @OptionalCustomCoding<StandardArrayCoder>
        public var instanceStates: [InstanceState]?

        public init(instanceStates: [InstanceState]? = nil) {
            self.instanceStates = instanceStates
        }

        private enum CodingKeys: String, CodingKey {
            case instanceStates = "InstanceStates"
        }
    }

    public struct DescribeLoadBalancerAttributesInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(loadBalancerName: String) {
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct DescribeLoadBalancerAttributesOutput: AWSDecodableShape {
        /// Information about the load balancer attributes.
        public let loadBalancerAttributes: LoadBalancerAttributes?

        public init(loadBalancerAttributes: LoadBalancerAttributes? = nil) {
            self.loadBalancerAttributes = loadBalancerAttributes
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerAttributes = "LoadBalancerAttributes"
        }
    }

    public struct DescribeLoadBalancerPoliciesInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String?
        /// The names of the policies.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyNames: [String]?

        public init(loadBalancerName: String? = nil, policyNames: [String]? = nil) {
            self.loadBalancerName = loadBalancerName
            self.policyNames = policyNames
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case policyNames = "PolicyNames"
        }
    }

    public struct DescribeLoadBalancerPoliciesOutput: AWSDecodableShape {
        /// Information about the policies.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyDescriptions: [PolicyDescription]?

        public init(policyDescriptions: [PolicyDescription]? = nil) {
            self.policyDescriptions = policyDescriptions
        }

        private enum CodingKeys: String, CodingKey {
            case policyDescriptions = "PolicyDescriptions"
        }
    }

    public struct DescribeLoadBalancerPolicyTypesInput: AWSEncodableShape {
        /// The names of the policy types. If no names are specified, describes all policy types defined by Elastic Load Balancing.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyTypeNames: [String]?

        public init(policyTypeNames: [String]? = nil) {
            self.policyTypeNames = policyTypeNames
        }

        private enum CodingKeys: String, CodingKey {
            case policyTypeNames = "PolicyTypeNames"
        }
    }

    public struct DescribeLoadBalancerPolicyTypesOutput: AWSDecodableShape {
        /// Information about the policy types.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyTypeDescriptions: [PolicyTypeDescription]?

        public init(policyTypeDescriptions: [PolicyTypeDescription]? = nil) {
            self.policyTypeDescriptions = policyTypeDescriptions
        }

        private enum CodingKeys: String, CodingKey {
            case policyTypeDescriptions = "PolicyTypeDescriptions"
        }
    }

    public struct DescribeTagsInput: AWSEncodableShape {
        /// The names of the load balancers.
        @CustomCoding<StandardArrayCoder>
        public var loadBalancerNames: [String]

        public init(loadBalancerNames: [String]) {
            self.loadBalancerNames = loadBalancerNames
        }

        public func validate(name: String) throws {
            try self.validate(self.loadBalancerNames, name: "loadBalancerNames", parent: name, max: 20)
            try self.validate(self.loadBalancerNames, name: "loadBalancerNames", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerNames = "LoadBalancerNames"
        }
    }

    public struct DescribeTagsOutput: AWSDecodableShape {
        /// Information about the tags.
        @OptionalCustomCoding<StandardArrayCoder>
        public var tagDescriptions: [TagDescription]?

        public init(tagDescriptions: [TagDescription]? = nil) {
            self.tagDescriptions = tagDescriptions
        }

        private enum CodingKeys: String, CodingKey {
            case tagDescriptions = "TagDescriptions"
        }
    }

    public struct DetachLoadBalancerFromSubnetsInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The IDs of the subnets.
        @CustomCoding<StandardArrayCoder>
        public var subnets: [String]

        public init(loadBalancerName: String, subnets: [String]) {
            self.loadBalancerName = loadBalancerName
            self.subnets = subnets
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case subnets = "Subnets"
        }
    }

    public struct DetachLoadBalancerFromSubnetsOutput: AWSDecodableShape {
        /// The IDs of the remaining subnets for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var subnets: [String]?

        public init(subnets: [String]? = nil) {
            self.subnets = subnets
        }

        private enum CodingKeys: String, CodingKey {
            case subnets = "Subnets"
        }
    }

    public struct HealthCheck: AWSEncodableShape & AWSDecodableShape {
        /// The number of consecutive health checks successes required before moving the instance to the Healthy state.
        public let healthyThreshold: Int
        /// The approximate interval, in seconds, between health checks of an individual instance.
        public let interval: Int
        /// The instance being checked. The protocol is either TCP, HTTP, HTTPS, or SSL. The range of valid ports is one (1) through 65535. TCP is the default, specified as a TCP: port pair, for example "TCP:5000". In this case, a health check simply attempts to open a TCP connection to the instance on the specified port. Failure to connect within the configured timeout is considered unhealthy. SSL is also specified as SSL: port pair, for example, SSL:5000. For HTTP/HTTPS, you must include a ping path in the string. HTTP is specified as a HTTP:port;/;PathToPing; grouping, for example "HTTP:80/weather/us/wa/seattle". In this case, a HTTP GET request is issued to the instance on the given port and path. Any answer other than "200 OK" within the timeout period is considered unhealthy. The total length of the HTTP ping target must be 1024 16-bit Unicode characters or less.
        public let target: String
        /// The amount of time, in seconds, during which no response means a failed health check. This value must be less than the Interval value.
        public let timeout: Int
        /// The number of consecutive health check failures required before moving the instance to the Unhealthy state.
        public let unhealthyThreshold: Int

        public init(healthyThreshold: Int, interval: Int, target: String, timeout: Int, unhealthyThreshold: Int) {
            self.healthyThreshold = healthyThreshold
            self.interval = interval
            self.target = target
            self.timeout = timeout
            self.unhealthyThreshold = unhealthyThreshold
        }

        public func validate(name: String) throws {
            try self.validate(self.healthyThreshold, name: "healthyThreshold", parent: name, max: 10)
            try self.validate(self.healthyThreshold, name: "healthyThreshold", parent: name, min: 2)
            try self.validate(self.interval, name: "interval", parent: name, max: 300)
            try self.validate(self.interval, name: "interval", parent: name, min: 5)
            try self.validate(self.timeout, name: "timeout", parent: name, max: 60)
            try self.validate(self.timeout, name: "timeout", parent: name, min: 2)
            try self.validate(self.unhealthyThreshold, name: "unhealthyThreshold", parent: name, max: 10)
            try self.validate(self.unhealthyThreshold, name: "unhealthyThreshold", parent: name, min: 2)
        }

        private enum CodingKeys: String, CodingKey {
            case healthyThreshold = "HealthyThreshold"
            case interval = "Interval"
            case target = "Target"
            case timeout = "Timeout"
            case unhealthyThreshold = "UnhealthyThreshold"
        }
    }

    public struct Instance: AWSEncodableShape & AWSDecodableShape {
        /// The instance ID.
        public let instanceId: String?

        public init(instanceId: String? = nil) {
            self.instanceId = instanceId
        }

        private enum CodingKeys: String, CodingKey {
            case instanceId = "InstanceId"
        }
    }

    public struct InstanceState: AWSDecodableShape {
        /// A description of the instance state. This string can contain one or more of the following messages.    N/A     A transient error occurred. Please try again later.     Instance has failed at least the UnhealthyThreshold number of health checks consecutively.     Instance has not passed the configured HealthyThreshold number of health checks consecutively.     Instance registration is still in progress.     Instance is in the EC2 Availability Zone for which LoadBalancer is not configured to route traffic to.     Instance is not currently registered with the LoadBalancer.     Instance deregistration currently in progress.     Disable Availability Zone is currently in progress.     Instance is in pending state.     Instance is in stopped state.     Instance is in terminated state.
        public let description: String?
        /// The ID of the instance.
        public let instanceId: String?
        /// Information about the cause of OutOfService instances. Specifically, whether the cause is Elastic Load Balancing or the instance. Valid values: ELB | Instance | N/A
        public let reasonCode: String?
        /// The current state of the instance. Valid values: InService | OutOfService | Unknown
        public let state: String?

        public init(description: String? = nil, instanceId: String? = nil, reasonCode: String? = nil, state: String? = nil) {
            self.description = description
            self.instanceId = instanceId
            self.reasonCode = reasonCode
            self.state = state
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case instanceId = "InstanceId"
            case reasonCode = "ReasonCode"
            case state = "State"
        }
    }

    public struct LBCookieStickinessPolicy: AWSDecodableShape {
        /// The time period, in seconds, after which the cookie should be considered stale. If this parameter is not specified, the stickiness session lasts for the duration of the browser session.
        public let cookieExpirationPeriod: Int64?
        /// The name of the policy. This name must be unique within the set of policies for this load balancer.
        public let policyName: String?

        public init(cookieExpirationPeriod: Int64? = nil, policyName: String? = nil) {
            self.cookieExpirationPeriod = cookieExpirationPeriod
            self.policyName = policyName
        }

        private enum CodingKeys: String, CodingKey {
            case cookieExpirationPeriod = "CookieExpirationPeriod"
            case policyName = "PolicyName"
        }
    }

    public struct Limit: AWSDecodableShape {
        /// The maximum value of the limit.
        public let max: String?
        /// The name of the limit. The possible values are:   classic-listeners   classic-load-balancers   classic-registered-instances
        public let name: String?

        public init(max: String? = nil, name: String? = nil) {
            self.max = max
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case max = "Max"
            case name = "Name"
        }
    }

    public struct Listener: AWSEncodableShape & AWSDecodableShape {
        /// The port on which the instance is listening.
        public let instancePort: Int
        /// The protocol to use for routing traffic to instances: HTTP, HTTPS, TCP, or SSL. If the front-end protocol is TCP or SSL, the back-end protocol must be TCP or SSL.  If the front-end protocol is HTTP or HTTPS, the back-end protocol must be HTTP or HTTPS. If there is another listener with the same InstancePort whose InstanceProtocol is secure, (HTTPS or SSL), the listener's InstanceProtocol must also be secure.  If there is another listener with the same InstancePort whose InstanceProtocol is HTTP or TCP, the listener's InstanceProtocol must be HTTP or TCP.
        public let instanceProtocol: String?
        /// The port on which the load balancer is listening. On EC2-VPC, you can specify any port from the range 1-65535. On EC2-Classic, you can specify any port from the following list: 25, 80, 443, 465, 587, 1024-65535.
        public let loadBalancerPort: Int
        /// The load balancer transport protocol to use for routing: HTTP, HTTPS, TCP, or SSL.
        public let `protocol`: String
        /// The Amazon Resource Name (ARN) of the server certificate.
        public let sslCertificateId: String?

        public init(instancePort: Int, instanceProtocol: String? = nil, loadBalancerPort: Int, protocol: String, sslCertificateId: String? = nil) {
            self.instancePort = instancePort
            self.instanceProtocol = instanceProtocol
            self.loadBalancerPort = loadBalancerPort
            self.`protocol` = `protocol`
            self.sslCertificateId = sslCertificateId
        }

        public func validate(name: String) throws {
            try self.validate(self.instancePort, name: "instancePort", parent: name, max: 65535)
            try self.validate(self.instancePort, name: "instancePort", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case instancePort = "InstancePort"
            case instanceProtocol = "InstanceProtocol"
            case loadBalancerPort = "LoadBalancerPort"
            case `protocol` = "Protocol"
            case sslCertificateId = "SSLCertificateId"
        }
    }

    public struct ListenerDescription: AWSDecodableShape {
        /// The listener.
        public let listener: Listener?
        /// The policies. If there are no policies enabled, the list is empty.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyNames: [String]?

        public init(listener: Listener? = nil, policyNames: [String]? = nil) {
            self.listener = listener
            self.policyNames = policyNames
        }

        private enum CodingKeys: String, CodingKey {
            case listener = "Listener"
            case policyNames = "PolicyNames"
        }
    }

    public struct LoadBalancerAttributes: AWSEncodableShape & AWSDecodableShape {
        /// If enabled, the load balancer captures detailed information of all requests and delivers the information to the Amazon S3 bucket that you specify. For more information, see Enable Access Logs in the Classic Load Balancers Guide.
        public let accessLog: AccessLog?
        /// Any additional attributes.
        @OptionalCustomCoding<StandardArrayCoder>
        public var additionalAttributes: [AdditionalAttribute]?
        /// If enabled, the load balancer allows existing requests to complete before the load balancer shifts traffic away from a deregistered or unhealthy instance. For more information, see Configure Connection Draining in the Classic Load Balancers Guide.
        public let connectionDraining: ConnectionDraining?
        /// If enabled, the load balancer allows the connections to remain idle (no data is sent over the connection) for the specified duration. By default, Elastic Load Balancing maintains a 60-second idle connection timeout for both front-end and back-end connections of your load balancer. For more information, see Configure Idle Connection Timeout in the Classic Load Balancers Guide.
        public let connectionSettings: ConnectionSettings?
        /// If enabled, the load balancer routes the request traffic evenly across all instances regardless of the Availability Zones.  For more information, see Configure Cross-Zone Load Balancing in the Classic Load Balancers Guide.
        public let crossZoneLoadBalancing: CrossZoneLoadBalancing?

        public init(accessLog: AccessLog? = nil, additionalAttributes: [AdditionalAttribute]? = nil, connectionDraining: ConnectionDraining? = nil, connectionSettings: ConnectionSettings? = nil, crossZoneLoadBalancing: CrossZoneLoadBalancing? = nil) {
            self.accessLog = accessLog
            self.additionalAttributes = additionalAttributes
            self.connectionDraining = connectionDraining
            self.connectionSettings = connectionSettings
            self.crossZoneLoadBalancing = crossZoneLoadBalancing
        }

        public func validate(name: String) throws {
            try self.additionalAttributes?.forEach {
                try $0.validate(name: "\(name).additionalAttributes[]")
            }
            try self.validate(self.additionalAttributes, name: "additionalAttributes", parent: name, max: 10)
            try self.connectionSettings?.validate(name: "\(name).connectionSettings")
        }

        private enum CodingKeys: String, CodingKey {
            case accessLog = "AccessLog"
            case additionalAttributes = "AdditionalAttributes"
            case connectionDraining = "ConnectionDraining"
            case connectionSettings = "ConnectionSettings"
            case crossZoneLoadBalancing = "CrossZoneLoadBalancing"
        }
    }

    public struct LoadBalancerDescription: AWSDecodableShape {
        /// The Availability Zones for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var availabilityZones: [String]?
        /// Information about your EC2 instances.
        @OptionalCustomCoding<StandardArrayCoder>
        public var backendServerDescriptions: [BackendServerDescription]?
        /// The DNS name of the load balancer. For more information, see Configure a Custom Domain Name  in the Classic Load Balancers Guide.
        public let canonicalHostedZoneName: String?
        /// The ID of the Amazon Route 53 hosted zone for the load balancer.
        public let canonicalHostedZoneNameID: String?
        /// The date and time the load balancer was created.
        public let createdTime: Date?
        /// The DNS name of the load balancer.
        public let dnsName: String?
        /// Information about the health checks conducted on the load balancer.
        public let healthCheck: HealthCheck?
        /// The IDs of the instances for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var instances: [Instance]?
        /// The listeners for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var listenerDescriptions: [ListenerDescription]?
        /// The name of the load balancer.
        public let loadBalancerName: String?
        /// The policies defined for the load balancer.
        public let policies: Policies?
        /// The type of load balancer. Valid only for load balancers in a VPC. If Scheme is internet-facing, the load balancer has a public DNS name that resolves to a public IP address. If Scheme is internal, the load balancer has a public  DNS name that resolves to a private IP address.
        public let scheme: String?
        /// The security groups for the load balancer. Valid only for load balancers in a VPC.
        @OptionalCustomCoding<StandardArrayCoder>
        public var securityGroups: [String]?
        /// The security group for the load balancer, which you can use as part of your inbound rules for your registered instances.  To only allow traffic from load balancers, add a security group rule that specifies this source security group as the inbound source.
        public let sourceSecurityGroup: SourceSecurityGroup?
        /// The IDs of the subnets for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var subnets: [String]?
        /// The ID of the VPC for the load balancer.
        public let vpcId: String?

        public init(availabilityZones: [String]? = nil, backendServerDescriptions: [BackendServerDescription]? = nil, canonicalHostedZoneName: String? = nil, canonicalHostedZoneNameID: String? = nil, createdTime: Date? = nil, dnsName: String? = nil, healthCheck: HealthCheck? = nil, instances: [Instance]? = nil, listenerDescriptions: [ListenerDescription]? = nil, loadBalancerName: String? = nil, policies: Policies? = nil, scheme: String? = nil, securityGroups: [String]? = nil, sourceSecurityGroup: SourceSecurityGroup? = nil, subnets: [String]? = nil, vpcId: String? = nil) {
            self.availabilityZones = availabilityZones
            self.backendServerDescriptions = backendServerDescriptions
            self.canonicalHostedZoneName = canonicalHostedZoneName
            self.canonicalHostedZoneNameID = canonicalHostedZoneNameID
            self.createdTime = createdTime
            self.dnsName = dnsName
            self.healthCheck = healthCheck
            self.instances = instances
            self.listenerDescriptions = listenerDescriptions
            self.loadBalancerName = loadBalancerName
            self.policies = policies
            self.scheme = scheme
            self.securityGroups = securityGroups
            self.sourceSecurityGroup = sourceSecurityGroup
            self.subnets = subnets
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case backendServerDescriptions = "BackendServerDescriptions"
            case canonicalHostedZoneName = "CanonicalHostedZoneName"
            case canonicalHostedZoneNameID = "CanonicalHostedZoneNameID"
            case createdTime = "CreatedTime"
            case dnsName = "DNSName"
            case healthCheck = "HealthCheck"
            case instances = "Instances"
            case listenerDescriptions = "ListenerDescriptions"
            case loadBalancerName = "LoadBalancerName"
            case policies = "Policies"
            case scheme = "Scheme"
            case securityGroups = "SecurityGroups"
            case sourceSecurityGroup = "SourceSecurityGroup"
            case subnets = "Subnets"
            case vpcId = "VPCId"
        }
    }

    public struct ModifyLoadBalancerAttributesInput: AWSEncodableShape {
        /// The attributes for the load balancer.
        public let loadBalancerAttributes: LoadBalancerAttributes
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(loadBalancerAttributes: LoadBalancerAttributes, loadBalancerName: String) {
            self.loadBalancerAttributes = loadBalancerAttributes
            self.loadBalancerName = loadBalancerName
        }

        public func validate(name: String) throws {
            try self.loadBalancerAttributes.validate(name: "\(name).loadBalancerAttributes")
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerAttributes = "LoadBalancerAttributes"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct ModifyLoadBalancerAttributesOutput: AWSDecodableShape {
        /// Information about the load balancer attributes.
        public let loadBalancerAttributes: LoadBalancerAttributes?
        /// The name of the load balancer.
        public let loadBalancerName: String?

        public init(loadBalancerAttributes: LoadBalancerAttributes? = nil, loadBalancerName: String? = nil) {
            self.loadBalancerAttributes = loadBalancerAttributes
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerAttributes = "LoadBalancerAttributes"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct Policies: AWSDecodableShape {
        /// The stickiness policies created using CreateAppCookieStickinessPolicy.
        @OptionalCustomCoding<StandardArrayCoder>
        public var appCookieStickinessPolicies: [AppCookieStickinessPolicy]?
        /// The stickiness policies created using CreateLBCookieStickinessPolicy.
        @OptionalCustomCoding<StandardArrayCoder>
        public var lbCookieStickinessPolicies: [LBCookieStickinessPolicy]?
        /// The policies other than the stickiness policies.
        @OptionalCustomCoding<StandardArrayCoder>
        public var otherPolicies: [String]?

        public init(appCookieStickinessPolicies: [AppCookieStickinessPolicy]? = nil, lbCookieStickinessPolicies: [LBCookieStickinessPolicy]? = nil, otherPolicies: [String]? = nil) {
            self.appCookieStickinessPolicies = appCookieStickinessPolicies
            self.lbCookieStickinessPolicies = lbCookieStickinessPolicies
            self.otherPolicies = otherPolicies
        }

        private enum CodingKeys: String, CodingKey {
            case appCookieStickinessPolicies = "AppCookieStickinessPolicies"
            case lbCookieStickinessPolicies = "LBCookieStickinessPolicies"
            case otherPolicies = "OtherPolicies"
        }
    }

    public struct PolicyAttribute: AWSEncodableShape {
        /// The name of the attribute.
        public let attributeName: String?
        /// The value of the attribute.
        public let attributeValue: String?

        public init(attributeName: String? = nil, attributeValue: String? = nil) {
            self.attributeName = attributeName
            self.attributeValue = attributeValue
        }

        private enum CodingKeys: String, CodingKey {
            case attributeName = "AttributeName"
            case attributeValue = "AttributeValue"
        }
    }

    public struct PolicyAttributeDescription: AWSDecodableShape {
        /// The name of the attribute.
        public let attributeName: String?
        /// The value of the attribute.
        public let attributeValue: String?

        public init(attributeName: String? = nil, attributeValue: String? = nil) {
            self.attributeName = attributeName
            self.attributeValue = attributeValue
        }

        private enum CodingKeys: String, CodingKey {
            case attributeName = "AttributeName"
            case attributeValue = "AttributeValue"
        }
    }

    public struct PolicyAttributeTypeDescription: AWSDecodableShape {
        /// The name of the attribute.
        public let attributeName: String?
        /// The type of the attribute. For example, Boolean or Integer.
        public let attributeType: String?
        /// The cardinality of the attribute.  Valid values:   ONE(1) : Single value required   ZERO_OR_ONE(0..1) : Up to one value is allowed   ZERO_OR_MORE(0..*) : Optional. Multiple values are allowed   ONE_OR_MORE(1..*0) : Required. Multiple values are allowed
        public let cardinality: String?
        /// The default value of the attribute, if applicable.
        public let defaultValue: String?
        /// A description of the attribute.
        public let description: String?

        public init(attributeName: String? = nil, attributeType: String? = nil, cardinality: String? = nil, defaultValue: String? = nil, description: String? = nil) {
            self.attributeName = attributeName
            self.attributeType = attributeType
            self.cardinality = cardinality
            self.defaultValue = defaultValue
            self.description = description
        }

        private enum CodingKeys: String, CodingKey {
            case attributeName = "AttributeName"
            case attributeType = "AttributeType"
            case cardinality = "Cardinality"
            case defaultValue = "DefaultValue"
            case description = "Description"
        }
    }

    public struct PolicyDescription: AWSDecodableShape {
        /// The policy attributes.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyAttributeDescriptions: [PolicyAttributeDescription]?
        /// The name of the policy.
        public let policyName: String?
        /// The name of the policy type.
        public let policyTypeName: String?

        public init(policyAttributeDescriptions: [PolicyAttributeDescription]? = nil, policyName: String? = nil, policyTypeName: String? = nil) {
            self.policyAttributeDescriptions = policyAttributeDescriptions
            self.policyName = policyName
            self.policyTypeName = policyTypeName
        }

        private enum CodingKeys: String, CodingKey {
            case policyAttributeDescriptions = "PolicyAttributeDescriptions"
            case policyName = "PolicyName"
            case policyTypeName = "PolicyTypeName"
        }
    }

    public struct PolicyTypeDescription: AWSDecodableShape {
        /// A description of the policy type.
        public let description: String?
        /// The description of the policy attributes associated with the policies defined by Elastic Load Balancing.
        @OptionalCustomCoding<StandardArrayCoder>
        public var policyAttributeTypeDescriptions: [PolicyAttributeTypeDescription]?
        /// The name of the policy type.
        public let policyTypeName: String?

        public init(description: String? = nil, policyAttributeTypeDescriptions: [PolicyAttributeTypeDescription]? = nil, policyTypeName: String? = nil) {
            self.description = description
            self.policyAttributeTypeDescriptions = policyAttributeTypeDescriptions
            self.policyTypeName = policyTypeName
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case policyAttributeTypeDescriptions = "PolicyAttributeTypeDescriptions"
            case policyTypeName = "PolicyTypeName"
        }
    }

    public struct RegisterEndPointsInput: AWSEncodableShape {
        /// The IDs of the instances.
        @CustomCoding<StandardArrayCoder>
        public var instances: [Instance]
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(instances: [Instance], loadBalancerName: String) {
            self.instances = instances
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case instances = "Instances"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct RegisterEndPointsOutput: AWSDecodableShape {
        /// The updated list of instances for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var instances: [Instance]?

        public init(instances: [Instance]? = nil) {
            self.instances = instances
        }

        private enum CodingKeys: String, CodingKey {
            case instances = "Instances"
        }
    }

    public struct RemoveAvailabilityZonesInput: AWSEncodableShape {
        /// The Availability Zones.
        @CustomCoding<StandardArrayCoder>
        public var availabilityZones: [String]
        /// The name of the load balancer.
        public let loadBalancerName: String

        public init(availabilityZones: [String], loadBalancerName: String) {
            self.availabilityZones = availabilityZones
            self.loadBalancerName = loadBalancerName
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case loadBalancerName = "LoadBalancerName"
        }
    }

    public struct RemoveAvailabilityZonesOutput: AWSDecodableShape {
        /// The remaining Availability Zones for the load balancer.
        @OptionalCustomCoding<StandardArrayCoder>
        public var availabilityZones: [String]?

        public init(availabilityZones: [String]? = nil) {
            self.availabilityZones = availabilityZones
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
        }
    }

    public struct RemoveTagsInput: AWSEncodableShape {
        /// The name of the load balancer. You can specify a maximum of one load balancer name.
        @CustomCoding<StandardArrayCoder>
        public var loadBalancerNames: [String]
        /// The list of tag keys to remove.
        @CustomCoding<StandardArrayCoder>
        public var tags: [TagKeyOnly]

        public init(loadBalancerNames: [String], tags: [TagKeyOnly]) {
            self.loadBalancerNames = loadBalancerNames
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerNames = "LoadBalancerNames"
            case tags = "Tags"
        }
    }

    public struct RemoveTagsOutput: AWSDecodableShape {
        public init() {}
    }

    public struct SetLoadBalancerListenerSSLCertificateInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The port that uses the specified SSL certificate.
        public let loadBalancerPort: Int
        /// The Amazon Resource Name (ARN) of the SSL certificate.
        public let sslCertificateId: String

        public init(loadBalancerName: String, loadBalancerPort: Int, sslCertificateId: String) {
            self.loadBalancerName = loadBalancerName
            self.loadBalancerPort = loadBalancerPort
            self.sslCertificateId = sslCertificateId
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case loadBalancerPort = "LoadBalancerPort"
            case sslCertificateId = "SSLCertificateId"
        }
    }

    public struct SetLoadBalancerListenerSSLCertificateOutput: AWSDecodableShape {
        public init() {}
    }

    public struct SetLoadBalancerPoliciesForBackendServerInput: AWSEncodableShape {
        /// The port number associated with the EC2 instance.
        public let instancePort: Int
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The names of the policies. If the list is empty, then all current polices are removed from the EC2 instance.
        @CustomCoding<StandardArrayCoder>
        public var policyNames: [String]

        public init(instancePort: Int, loadBalancerName: String, policyNames: [String]) {
            self.instancePort = instancePort
            self.loadBalancerName = loadBalancerName
            self.policyNames = policyNames
        }

        private enum CodingKeys: String, CodingKey {
            case instancePort = "InstancePort"
            case loadBalancerName = "LoadBalancerName"
            case policyNames = "PolicyNames"
        }
    }

    public struct SetLoadBalancerPoliciesForBackendServerOutput: AWSDecodableShape {
        public init() {}
    }

    public struct SetLoadBalancerPoliciesOfListenerInput: AWSEncodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String
        /// The external port of the load balancer.
        public let loadBalancerPort: Int
        /// The names of the policies. This list must include all policies to be enabled. If you omit a policy that is currently enabled, it is disabled. If the list is empty, all current policies are disabled.
        @CustomCoding<StandardArrayCoder>
        public var policyNames: [String]

        public init(loadBalancerName: String, loadBalancerPort: Int, policyNames: [String]) {
            self.loadBalancerName = loadBalancerName
            self.loadBalancerPort = loadBalancerPort
            self.policyNames = policyNames
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case loadBalancerPort = "LoadBalancerPort"
            case policyNames = "PolicyNames"
        }
    }

    public struct SetLoadBalancerPoliciesOfListenerOutput: AWSDecodableShape {
        public init() {}
    }

    public struct SourceSecurityGroup: AWSDecodableShape {
        /// The name of the security group.
        public let groupName: String?
        /// The owner of the security group.
        public let ownerAlias: Int?

        public init(groupName: String? = nil, ownerAlias: Int? = nil) {
            self.groupName = groupName
            self.ownerAlias = ownerAlias
        }

        private enum CodingKeys: String, CodingKey {
            case groupName = "GroupName"
            case ownerAlias = "OwnerAlias"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The key of the tag.
        public let key: String
        /// The value of the tag.
        public let value: String?

        public init(key: String, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagDescription: AWSDecodableShape {
        /// The name of the load balancer.
        public let loadBalancerName: String?
        /// The tags.
        @OptionalCustomCoding<StandardArrayCoder>
        public var tags: [Tag]?

        public init(loadBalancerName: String? = nil, tags: [Tag]? = nil) {
            self.loadBalancerName = loadBalancerName
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case loadBalancerName = "LoadBalancerName"
            case tags = "Tags"
        }
    }

    public struct TagKeyOnly: AWSEncodableShape {
        /// The name of the key.
        public let key: String?

        public init(key: String? = nil) {
            self.key = key
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
        }
    }
}

// MARK: - Errors

/// Error enum for ElasticLoadBalancing
public struct ElasticLoadBalancingErrorType: AWSErrorType {
    enum Code: String {
        case accessPointNotFoundException = "LoadBalancerNotFound"
        case certificateNotFoundException = "CertificateNotFound"
        case dependencyThrottleException = "DependencyThrottle"
        case duplicateAccessPointNameException = "DuplicateLoadBalancerName"
        case duplicateListenerException = "DuplicateListener"
        case duplicatePolicyNameException = "DuplicatePolicyName"
        case duplicateTagKeysException = "DuplicateTagKeys"
        case invalidConfigurationRequestException = "InvalidConfigurationRequest"
        case invalidEndPointException = "InvalidInstance"
        case invalidSchemeException = "InvalidScheme"
        case invalidSecurityGroupException = "InvalidSecurityGroup"
        case invalidSubnetException = "InvalidSubnet"
        case listenerNotFoundException = "ListenerNotFound"
        case loadBalancerAttributeNotFoundException = "LoadBalancerAttributeNotFound"
        case operationNotPermittedException = "OperationNotPermitted"
        case policyNotFoundException = "PolicyNotFound"
        case policyTypeNotFoundException = "PolicyTypeNotFound"
        case subnetNotFoundException = "SubnetNotFound"
        case tooManyAccessPointsException = "TooManyLoadBalancers"
        case tooManyPoliciesException = "TooManyPolicies"
        case tooManyTagsException = "TooManyTags"
        case unsupportedProtocolException = "UnsupportedProtocol"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize ElasticLoadBalancing
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// The specified load balancer does not exist.
    public static var accessPointNotFoundException: Self { .init(.accessPointNotFoundException) }
    /// The specified ARN does not refer to a valid SSL certificate in AWS Identity and Access Management (IAM)  or AWS Certificate Manager (ACM). Note that if you recently uploaded the certificate to IAM, this error might  indicate that the certificate is not fully available yet.
    public static var certificateNotFoundException: Self { .init(.certificateNotFoundException) }
    /// A request made by Elastic Load Balancing to another service exceeds the maximum request rate permitted for your account.
    public static var dependencyThrottleException: Self { .init(.dependencyThrottleException) }
    /// The specified load balancer name already exists for this account.
    public static var duplicateAccessPointNameException: Self { .init(.duplicateAccessPointNameException) }
    /// A listener already exists for the specified load balancer name and port, but with a different instance port, protocol, or SSL certificate.
    public static var duplicateListenerException: Self { .init(.duplicateListenerException) }
    /// A policy with the specified name already exists for this load balancer.
    public static var duplicatePolicyNameException: Self { .init(.duplicatePolicyNameException) }
    /// A tag key was specified more than once.
    public static var duplicateTagKeysException: Self { .init(.duplicateTagKeysException) }
    /// The requested configuration change is not valid.
    public static var invalidConfigurationRequestException: Self { .init(.invalidConfigurationRequestException) }
    /// The specified endpoint is not valid.
    public static var invalidEndPointException: Self { .init(.invalidEndPointException) }
    /// The specified value for the schema is not valid. You can only specify a scheme for load balancers in a VPC.
    public static var invalidSchemeException: Self { .init(.invalidSchemeException) }
    /// One or more of the specified security groups do not exist.
    public static var invalidSecurityGroupException: Self { .init(.invalidSecurityGroupException) }
    /// The specified VPC has no associated Internet gateway.
    public static var invalidSubnetException: Self { .init(.invalidSubnetException) }
    /// The load balancer does not have a listener configured at the specified port.
    public static var listenerNotFoundException: Self { .init(.listenerNotFoundException) }
    /// The specified load balancer attribute does not exist.
    public static var loadBalancerAttributeNotFoundException: Self { .init(.loadBalancerAttributeNotFoundException) }
    /// This operation is not allowed.
    public static var operationNotPermittedException: Self { .init(.operationNotPermittedException) }
    /// One or more of the specified policies do not exist.
    public static var policyNotFoundException: Self { .init(.policyNotFoundException) }
    /// One or more of the specified policy types do not exist.
    public static var policyTypeNotFoundException: Self { .init(.policyTypeNotFoundException) }
    /// One or more of the specified subnets do not exist.
    public static var subnetNotFoundException: Self { .init(.subnetNotFoundException) }
    /// The quota for the number of load balancers has been reached.
    public static var tooManyAccessPointsException: Self { .init(.tooManyAccessPointsException) }
    /// The quota for the number of policies for this load balancer has been reached.
    public static var tooManyPoliciesException: Self { .init(.tooManyPoliciesException) }
    /// The quota for the number of tags that can be assigned to a load balancer has been reached.
    public static var tooManyTagsException: Self { .init(.tooManyTagsException) }
    /// The specified protocol or signature version is not supported.
    public static var unsupportedProtocolException: Self { .init(.unsupportedProtocolException) }
}

extension ElasticLoadBalancingErrorType: Equatable {
    public static func == (lhs: ElasticLoadBalancingErrorType, rhs: ElasticLoadBalancingErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension ElasticLoadBalancingErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
